package com.breeze.blockchain.controller.admin;

import static com.breeze.blockchain.common.exception.BizErrorCode.LOGIN_ERROR;

import cn.dev33.satoken.exception.DisableServiceException;
import com.breeze.blockchain.auth.util.AdminUserUtil;
import com.breeze.blockchain.common.async.AsyncTaskFactory;
import com.breeze.blockchain.common.enums.LoginStatusEnum;
import com.breeze.blockchain.controller.admin.form.admin.AdminPageForm;
import com.breeze.blockchain.controller.admin.form.login.LoginCommand;
import com.breeze.blockchain.mybatis.entity.AdminDo;
import com.breeze.blockchain.service.AdminService;
import com.breeze.components.core.exception.ApiException;
import com.breeze.components.core.thread.ThreadPoolManager;
import com.breeze.components.web.core.ResponseDTO;
import com.mybatisflex.core.paginate.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 管理员表 控制层。
 *
 * @author breeze
 * @since 2024-05-11 22:55:04
 */
@RestController
@Tag(name = "管理员表接口")
@RequestMapping("api/admin")
@Slf4j
public class AdminController {

  @Resource private AdminService adminService;

  @PostMapping("login")
  @Operation(summary = "登录接口")
  public ResponseDTO<AdminDo> login(@RequestBody @Validated LoginCommand loginCommand) {
    try {
      AdminDo admin = adminService.login(loginCommand.getUsername(), loginCommand.getPassword());
      return ResponseDTO.ok(admin);
    } catch (ApiException | DisableServiceException e) {
      ThreadPoolManager.execute(
          AsyncTaskFactory.loginInfoTask(
              loginCommand.getUsername(), LoginStatusEnum.LOGIN_FAIL, e.getMessage()));
      throw e;
    } catch (Exception e) {
      log.error("存在登录异常：{}", loginCommand, e);
      ThreadPoolManager.execute(
          AsyncTaskFactory.loginInfoTask(
              loginCommand.getUsername(), LoginStatusEnum.LOGIN_FAIL, e.getMessage()));
      throw new ApiException(e, LOGIN_ERROR, e.getMessage());
    }
  }

  @Operation(summary = "注销")
  @GetMapping("logout")
  public ResponseDTO<Void> logout() {
    AdminUserUtil.logout(AdminUserUtil.getLoginId());
    return ResponseDTO.ok();
  }

  @Operation(summary = "账户封禁")
  @GetMapping("disable")
  public ResponseDTO<Void> disable(@RequestParam Long id) {
    // 先踢下线
    AdminUserUtil.kickout(id);
    // 再封禁账号
    AdminUserUtil.disable(id, -1);
    return ResponseDTO.ok();
  }

  @Operation(summary = "账户解禁")
  @GetMapping("untieDisable")
  public ResponseDTO<Void> untieDisable(@RequestParam Long id) {
    AdminUserUtil.untieDisable(id);
    return ResponseDTO.ok();
  }

  /**
   * 添加管理员表。
   *
   * @param admin 管理员表
   */
  @PostMapping("save")
  @Operation(summary = "保存管理员表")
  public ResponseDTO<Void> save(@RequestBody @Parameter(name = "管理员表") AdminDo admin) {
    adminService.saveAdmin(admin);
    return ResponseDTO.ok();
  }

  /**
   * 根据主键删除管理员表。
   *
   * @param id 主键
   */
  @GetMapping("remove")
  @Operation(summary = "根据主键管理员表")
  public ResponseDTO<Void> remove(@RequestParam @Parameter(name = "管理员表主键") Long id) {
    adminService.removeById(id);
    return ResponseDTO.ok();
  }

  /**
   * 根据主键更新管理员表。
   *
   * @param admin 管理员表
   */
  @PostMapping("update")
  @Operation(summary = "根据主键更新管理员表")
  public ResponseDTO<Boolean> update(@RequestBody @Parameter(name = "管理员表主键") AdminDo admin) {
    return ResponseDTO.ok(adminService.updateAdmin(admin));
  }

  /**
   * 根据管理员表主键获取详细信息。
   *
   * @param id 管理员表主键
   * @return 管理员表详情
   */
  @GetMapping("detail")
  @Operation(summary = "根据主键获取管理员表")
  public ResponseDTO<AdminDo> detail(@RequestParam Long id) {
    return ResponseDTO.ok(adminService.getById(id));
  }

  /**
   * 分页查询管理员表。
   *
   * @param form 分页对象
   * @return 分页对象
   */
  @PostMapping("page")
  @Operation(summary = "分页查询管理员表")
  public ResponseDTO<Page<AdminDo>> page(
      @RequestBody @Parameter(name = "分页信息") AdminPageForm form) {
    return ResponseDTO.ok(
        adminService.adminPage(
            form.toPage(), form.getUsername(), form.getMobile(), form.getNickname()));
  }
}
